﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ComputerBeacon.Csv;
using ComputerBeacon.Serialization;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace UnitTestProject1 {
    [TestClass]
    public class DeserializationTest {
        void AssertList<T>(List<T> result, T[] answer) {
            Assert.AreEqual(answer.Length, result.Count);
            var fields = typeof(T).GetFields();
            for (int i = 0; i < result.Count; i++) {
                foreach (var f in fields) Assert.AreEqual(f.GetValue(answer[i]), f.GetValue(result[i]));
            }
            var properties = typeof(T).GetProperties();
            for (int i = 0; i < result.Count; i++) {
                foreach (var p in properties) Assert.AreEqual(p.GetValue(answer[i], null), p.GetValue(result[i], null));
            }
        }

        [TestMethod]
        public void CarSimple() {
            var cars = Serialization.Deserialize<Car>(
                "Year,Make,Model,Length\r\n1997,Ford,E350,2.34\r\n2000,Mercury,Cougar,2.38"
            );

            var answer = new []{
                new Car{ Year = 1997, Make = "Ford", Model = "E350", Length = 2.34},
                new Car{ Year = 2000, Make = "Mercury", Model = "Cougar", Length = 2.38},
            };
            AssertList(cars, answer);
        }

        [TestMethod]
        public void CarComplex() { //with empty and quoted fields
            var prices = Serialization.Deserialize<CarPrice>(
                "Year,Make,Model,Description,Price\r\n" +
                "1997,Ford,E350,\"ac, abs, moon\",3000.00\r\n" +
                "1999,Chevy,\"Venture \"\"Extended Edition\"\"\",\"\",4900.00\r\n"+
                "1999,Chevy,\"Venture \"\"Extended Edition, Very Large\"\"\",,5000.00\r\n"+
                "1996,Jeep,Grand Cherokee,\"MUST SELL!\r\nair, moon roof, loaded\",4799.00"
            );

            var answer = new[]{
                new CarPrice{ Year = 1997, Make = "Ford", Model = "E350", Description = "ac, abs, moon", Price = 3000},
                new CarPrice{ Year = 1999, Make = "Chevy", Model = "Venture \"Extended Edition\"", Description = "", Price = 4900},
                new CarPrice{ Year = 1999, Make = "Chevy", Model = "Venture \"Extended Edition, Very Large\"", Description="", Price = 5000},
                new CarPrice{ Year = 1996, Make = "Jeep", Model = "Grand Cherokee", Description="MUST SELL!\r\nair, moon roof, loaded", Price = 4799}
            };
            AssertList(prices, answer);
        }

        [TestMethod]
        public void CarSimpleWithProperties() {
            var cars = Serialization.Deserialize<CarWithProperties>(
                "Year,Make,Model,Length\r\n1997,Ford,E350,2.34\r\n2000,Mercury,Cougar,2.38"
            );

            var answer = new[]{
                new CarWithProperties{ Year = 1997, Make = "Ford", Model = "E350", Length = 2.34},
                new CarWithProperties{ Year = 2000, Make = "Mercury", Model = "Cougar", Length = 2.38},
            };
            AssertList(cars, answer);
        }

        [TestMethod]
        [ExpectedException(typeof(FormatException))]
        public void InconsistentColumnCount() {
            var cars = Serialization.Deserialize<CarWithProperties>(
                "Year,Make,Model,Length,Extra Column\r\n1997,Ford,E350,2.34\r\n2000,Mercury,Cougar,2.38"
            );
        }

        [TestMethod]
        public void AllowTrailingEmptyLine() {
            var cars = Serialization.Deserialize<Car>(
                "Year,Make,Model,Length\r\n1997,Ford,E350,2.34\r\n2000,Mercury,Cougar,2.38\r\n"
            );

            var answer = new[]{
                new Car{ Year = 1997, Make = "Ford", Model = "E350", Length = 2.34},
                new Car{ Year = 2000, Make = "Mercury", Model = "Cougar", Length = 2.38},
            };
            AssertList(cars, answer);
        }
    }
}
